// Package ioc
// Created by GoLand
// @User: lenora
// @Date: 2023/12/17
// @Time: 17:43

package ioc

import (
	"camp/microbook/constant"
	"camp/microbook/internal/middlewares"
	"camp/microbook/internal/web"
	ijwt "camp/microbook/internal/web/jwt"
	"camp/microbook/pkg/ginx"
	iprometheus "camp/microbook/pkg/ginx/middleware/prometheus"
	"camp/microbook/pkg/logger"
	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/redis/go-redis/v9"
	"go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin"
	"strings"
	"time"
)

//NOTICE:使用依赖注入的话,每次新增了handler需要在InitWebServer中注入

func InitWebServer(mdls []gin.HandlerFunc,
	userHdl *web.UserHandler,
	comnHdl *web.CommonHandler,
	wechatHdl *web.OAuth2WechatHandler,
	artHdl *web.ArticleHandler) *gin.Engine {
	server := gin.Default()
	server.Use(mdls...)
	userHdl.RegisterRoutes(server)
	comnHdl.RegisterRoutes(server)
	wechatHdl.RegisterRoutes(server)
	artHdl.RegisterRoutes(server)
	return server
}

func InitMiddlewares(client redis.Cmdable, handler ijwt.Handler, log logger.Logger) []gin.HandlerFunc {
	p := iprometheus.NewBuilder(
		constant.NAMESPACE,
		constant.SUBSYSTEM,
		"gin_http",
		"default",
	)

	ginx.InitCounter(prometheus.CounterOpts{
		Namespace: constant.NAMESPACE,
		Subsystem: constant.SUBSYSTEM,
		Name:      "response_code",
	})
	return []gin.HandlerFunc{
		//跨域
		cors.New(cors.Config{
			AllowCredentials: true,
			AllowHeaders:     []string{"Content-Type", "Authorization"},
			//可以暴露给前端的header
			ExposeHeaders: []string{"x-jwt-token"},
			AllowOriginFunc: func(origin string) bool {
				if strings.HasPrefix(origin, "http://localhost") {
					return true
				}
				return strings.Contains(origin, "localhost is mine")
			},
			MaxAge: 12 * time.Hour,
		}),

		// redis 限流
		//ratelimit.NewBuilder(limiter.NewRedisSlidingWindowLimiter(client, time.Second, 100)).Build(),

		p.BuildResponseTime(),
		p.BuildActiveRequest(),

		otelgin.Middleware("microbook"),
		//请求日志
		//middlewares.NewLogMiddlewareBuilder(func(ctx context.Context, al middlewares.AccessLog) {
		//	log.Debug("", logger.Field{Key: "req", Value: al})
		//}, func(ctx context.Context, data string) {
		//	log.Debug("response error", logger.Field{Key: "errMsg", Value: data})
		//}).AllowReqBody().AllowRespBody().Build(),
		//jwt token
		middlewares.NewJwtMiddlewareBuilder(handler).CheckLogin(),
	}
}
